package com.pengtu.gsj.controller.system;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Properties;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import org.springframework.web.multipart.commons.CommonsMultipartFile;
import org.springframework.web.multipart.commons.CommonsMultipartResolver;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;

import com.pengtu.gsj.controller.base.BaseController;
import com.pengtu.gsj.dao.base.Page;
import com.pengtu.gsj.dao.base.QueryFilter;
import com.pengtu.gsj.dao.base.QueryFilter.MatchType;
import com.pengtu.gsj.entity.app.Banner;
import com.pengtu.gsj.entity.app.User;
import com.pengtu.gsj.entity.base.EntityMapForm;
import com.pengtu.gsj.interceptor.Token;
import com.pengtu.gsj.service.system.BannerService;
import com.pengtu.gsj.utils.ConfigUtils;
import com.pengtu.gsj.utils.PropertiesUtils;
import com.pengtu.gsj.utils.UpDownFileUtils;
import com.pengtu.gsj.utils.UserUtils;
import com.pengtu.gsj.utils.web.SpringMvcUtils;

/**
 * 
 * BannerController
 * 
 * 2017年4月18日 下午2:44:48
 * 
 * @version 1.0.0
 *
 */
@Controller
@RequestMapping("/banner/")
public class BannerController extends BaseController {

	@Autowired
	private BannerService bannerService;
	
	/**
	 * 
	 * loadEntity:
	 * 适用: 每个方法执行之前都会执行该方法
	 * @param id  主键id
	 * @return 返回持久对象或者新创建对象
	 * @exception 
	 * @since  1.0.0
	 */
	@ModelAttribute
	public Banner loadEntity(String id,Model model){
		Banner banner ;
		if (StringUtils.isNotEmpty(id)) {
			banner = bannerService.getBanner(id);
		}else {
			banner = new Banner();
		}
		model.addAttribute("top", SpringMvcUtils.getParameter("top"));
		model.addAttribute("left", SpringMvcUtils.getParameter("left"));
		return banner;
	}

	/**
	 * 
	 * getBanners:
	 * 适用:按属性要求获取banner列表
	 * @param page 对象集
	 * @param request 
	 * @return banner列表
	 * @exception 
	 * @since  1.0.0
	 */
	@ResponseBody
	@RequestMapping(value = "list", produces = "application/json; charset=utf-8")
	public Page<Banner> getBanners(Page<Banner> page,HttpServletRequest request) {
		QueryFilter queryFilter = QueryFilter.buildFromHttpRequest(request);
		if (!page.isOrderBySetted()) {
			page.setOrderBy("sort");
			page.setOrder(Page.ASC);
		}
		page = bannerService.findbanners(page, queryFilter);
		return page;
	}

	/**
	 * 
	 * saveBanner:
	 * 适用:保存对象
	 * @param file banner图片上传
	 * @param banner banner对象
	 * @param request 请求
	 * @return banner列表页面
	 * @throws Exception 
	 * @exception 
	 * @since  1.0.0
	 */
	@RequestMapping(value = "save",method=RequestMethod.POST)
	@Token(remove = true)
	public String saveBanner(@RequestParam(value = "file", required = false) MultipartFile multipartFile, @ModelAttribute Banner banner,HttpServletRequest request,RedirectAttributes attributes) throws Exception {
		String bannerPath = ConfigUtils.getConfig("upload.path");
		System.out.println("path:"+bannerPath);
		String fullpath =  "";
		//当文件不为空的时候才去更新文件
		if (StringUtils.isNotEmpty(multipartFile.getOriginalFilename())) {
			fullpath = UpDownFileUtils.fileUpload(multipartFile,bannerPath);
			banner.setPath(fullpath);
		}
		banner.setUploadPerson(UserUtils.getName());
		bannerService.saveBanner(banner);
		attributes.addFlashAttribute("msg", "保存成功！");
		attributes.addAttribute("top",	SpringMvcUtils.getParameter("top"));
		attributes.addAttribute("left", SpringMvcUtils.getParameter("left"));
		return "redirect:/banner/show.do";
	}
	
	/**
	 * 
	 * getIndexBanners:
	 * 适用:得到系统所有的banner 用户index页面
	 * @return 
	 * @exception 
	 * @since  1.0.0
	 */
	@RequestMapping(value = "indexBanner")
	@ResponseBody
	public List<Banner> getIndexBanners() {
		QueryFilter queryFilter = new QueryFilter();
		queryFilter.addFilter("isShow", "1", MatchType.EQ);
		List<Banner> list = bannerService.getBanners(queryFilter);
		return list;
	} 
	
	@RequestMapping("bannerDetail")
	public String showBannerDetailInfo(@ModelAttribute Banner banner) {
		return "banner/bannerDetail";
	}
	
	/**
	 * 
	 * deleteBanner:
	 * 适用:删除对象
	 * @param id
	 * @return banner列表页面
	 * @exception 
	 * @since  1.0.0
	 */
	@RequestMapping(value = "delete")
	public String deleteBanner(String id,RedirectAttributes attributes){
		bannerService.deleteBanner(id);
		attributes.addFlashAttribute("msg", "删除成功！");
		attributes.addAttribute("top",	SpringMvcUtils.getParameter("top"));
		attributes.addAttribute("left", SpringMvcUtils.getParameter("left"));
		return "redirect:/banner/show.do";
	}
 
	/**
	 * 
	 * saveTest:
	 * 适用:
	 * @param name
	 * @param user
	 * @param pathvar 
	 * @exception 
	 * @since  1.0.0
	 */
	@RequestMapping(value="/test/{pathvar}",method=RequestMethod.POST, produces=MediaType.APPLICATION_JSON_VALUE)
    public void saveTest(@RequestParam String name,@RequestBody User user,@PathVariable String pathvar){
        System.out.println(name);
        System.out.println(user);
        System.out.println(pathvar);
    }
	
	/**
	 * 
	 * bannerShow:
	 * 适用:展示页面跳转
	 * @param model
	 * @return banner列表页面
	 * @exception 
	 * @since  1.0.0
	 */
	@RequestMapping("show")
	public String bannerShow(Model model) {
		String msg = SpringMvcUtils.getParameter("msg");
		if (StringUtils.isNotEmpty(msg)) {
			model.addAttribute("msg", msg);
		}
		return "banner/bannerList";
	}

	// 获取参数的几种形式
	// 当地址栏为/banner/banner1.htm?id=10的时候,action中有三种接收方式
	/**
	 * 这样会把地址栏参数名为userid的值赋给参数id,如果用地址栏上的参数名为id,则接收不到 而且报404错误
	 * 
	 * @param id
	 * @return
	 */
	@RequestMapping("banner1")
	public String bannerData1(@RequestParam(value = "userid") String id) {
		System.out.println("id:" + id);
		return "banner/bannerList";
	}

	/**
	 * 这种情况下默认会把id作为参数名来进行接收赋值 如果参数前面加上@RequestParam注解,如果地址栏上面没有加上该注解的参数,
	 * 例如:id,那么会报404错误,找不到该路径 传递参数第一种形式：在形参中放入一个Model
	 * 
	 * @param id
	 * @return
	 */
	@RequestMapping("banner2")
	public String bannerData2(@RequestParam String id, Model model) {
		System.out.println("id:" + id);
		model.addAttribute("name", id);
		return "banner/bannerList";
	}

	/**
	 * 这种情况下也会默认把id作为参数名来进行接收赋值 传递参数第二种形式：在形参中放入一个map
	 * 
	 * @param id
	 * @return
	 */
	@RequestMapping("banner3")
	public String bannerData3(String id, Map<String, Object> map) {
		System.out.println("id:" + id);
		map.put("name", id);
		return "banner/bannerList";
	}

	@RequestMapping("banner4")
	public String bannerData4(HttpServletRequest request) {
		System.out.println("id:" + request.getParameter("id"));
		return "banner/bannerList";
	}

	/**
	 * 表单中input的name值和Controller的参数变量名保持一致，就能完成数据绑定， 如果不一致可以使用@RequestParam注解。
	 * 需要注意的是，如果Controller方法参数中定义的是基本数据类型， 但是从页面提交过来的数据为null或者”"的话，会出现数据转换的异常。
	 * 也就是必须保证表单传递过来的数据不能为null或”"，
	 * 所以，在开发过程中，对可能为空的数据，最好将参数数据类型定义成包装类型，具体参见下面的例子。
	 * 
	 */
	@RequestMapping("banner5")
	public String bannerData5(int count, Model model) {
		System.out.println("count:" + count);
		model.addAttribute("name", count);
		return "banner/bannerList";
	}

	@RequestMapping("banner6")
	public String bannerData6(Integer count, Model model) {
		System.out.println("count:" + count);
		model.addAttribute("name", count);
		return "banner/bannerList";
	}

	// List需要绑定在对象上，而不能直接写在Controller方法的参数中。需要在一个对象中定义user的list集合
	// public String data(List<User> users){}

	/**
	 * 此方法有bug 因为多个参数之间需要用的下标来指定 如果下标有跨度的话 比如 0 2 则保存的时候会保存三个对象
	 * 下标为1的对象的属性值都为null
	 * 
	 * @param users
	 * @return
	 */
	@RequestMapping("banner7")
	public String bannerData7(EntityMapForm<User> users) {
		for (Map.Entry<String, User> entity : users.getMap().entrySet()) {
			System.out.println("username:" + entity.getValue().getUsername());
			System.out.println("password:" + entity.getValue().getPassword());
		}
		return "banner/bannerList";
	}

	/**
	 * @RequestBody接收的是一个Json对象的字符串，而不是一个Json对象 当只有一个对象的时候 可以用表单的序列化来传递
	 *                                          传递过来的是一个json对象 不能用@requestBody
	 * @param users
	 * @return
	 */
	@RequestMapping("banner8")
	@ResponseBody
	public List<Banner> bannerData8(@RequestBody List<Banner> banners) {
		System.out.println("size:" + banners.size());
		return banners;
	}
	
	@RequestMapping("bannerEncode")
	public String bannerEncode(String name,Model model){
		System.out.println("name:"+name);
		return "banner/bannerDemo";
	}

	@RequestMapping("bannerDemo")
	public String bannerDemo() {
		return "banner/bannerDemo";
	}

	@RequestMapping("bannerbaseSave")
	public String bannerbaseSave() {
		return "banner/bannerbaseInput";
	}
	
	/**
	 * 
	 * bannerInput:
	 * 适用:新增/修改页面跳转
	 * @param id 唯一id标识
	 * @param model 对象
	 * @return 新增/修改页面
	 * @exception 
	 * @since  1.0.0
	 */
	@RequestMapping("input")
	@Token(save = true)
	public String bannerInput(@ModelAttribute Banner banner,Model model) {
		if(banner!=null){
			model.addAttribute("entity", banner);
		}
		return "banner/bannerInput";
	}
	
	/**
	 * 
	 * bannerImg:
	 * 适用: 获取图片到页面
	 * @param path
	 * @param model
	 * @param response
	 * @throws Exception 
	 * @exception 
	 * @since  1.0.0
	 */
	@RequestMapping("bannerImg")
    public @ResponseBody void bannerImg(String path,Model model,HttpServletResponse response) throws Exception{
		 response.setContentType("image/*");
		 Properties properties = PropertiesUtils.loadProperties("config.properties");
			String rootpath = properties.getProperty("upload.path");
		 if(StringUtils.isNotEmpty(path)){
	        FileInputStream fis = null; 
	        OutputStream os = null; 
	        try {
	        	fis = new FileInputStream(rootpath+path);
	        	os = response.getOutputStream();
	            int count = 0;
	            byte[] buffer = new byte[1024*8];
	            while ( (count = fis.read(buffer)) != -1 ){
	            	os.write(buffer, 0, count);
	            	os.flush();
	            }
	        }catch(Exception e){
	        	e.printStackTrace();
	        }finally {
	            try {
	            	if (fis != null) {
	            		fis.close();
					}
	            	if (os != null) {
	            		os.close();
	            	}
				} catch (IOException e) {
					e.printStackTrace();
				}
	        }
	        }
	    }
	
	
	@RequestMapping("bannerPDF")
	public String bannerPDF() {
		return "banner/bannerPdf";
	}

	/**
	 * 通过流的方式上传文件
	 * @param file
	 * @RequestParam("file") 将name=file控件得到的文件封装成CommonsMultipartFile 对象
	 * @return
	 * @throws IOException
	 */
	@RequestMapping("fileUpload1")
	public String fileUpload1(@RequestParam("file") CommonsMultipartFile file)
			throws IOException {
		 //用来检测程序运行时间
		System.err.println("1");
		long startTime = System.currentTimeMillis();
		System.out.println("fileName:" + file.getOriginalFilename());
		System.out.println("fileName:" + file.getName());
		//获取输出流
		OutputStream os = new FileOutputStream("F:/testupload/"
				+ System.currentTimeMillis() + file.getOriginalFilename());
		//获取输入流 CommonsMultipartFile 中可以直接得到文件的流
		InputStream in = file.getInputStream();
		int temp;
		//一个一个字节的读取并写入
		while ((temp = in.read()) != -1) {
			os.write(temp);
		}
		os.flush();
		os.close();
		in.close();
		long endTiem = System.currentTimeMillis();
		System.out.println("上传文件需要的时间为:" + (endTiem - startTime));
		return "redirect:/banner/show.do";
	}
	
	
	/**
	 * 采用file.Transto 来保存上传的文件
	 * @param file
	 * @return
	 * @throws IllegalStateException
	 * @throws IOException
	 */
	@RequestMapping("fileUpload2")
	public String fileUpload2(@RequestParam("file") CommonsMultipartFile file) throws IllegalStateException, IOException{
		System.err.println("2");
		Long startTime = System.currentTimeMillis();
		System.out.println("fileName:"+file.getOriginalFilename());
		String path = "F:/testupload/"+System.currentTimeMillis()+file.getOriginalFilename();
		file.transferTo(new File(path));
		Long endTime = System.currentTimeMillis();
		System.out.println("上传文件花费的时间为:"+(endTime-startTime));
		return "redirect:/banner/show.do"; 
	}
	
	
	/**
	 * 采用spring提供的上传文件的方法
	 * @param request
	 * @return
	 * @throws IOException
	 */
	@SuppressWarnings("rawtypes")
	@RequestMapping("fileUpload3")
	public String springUpload(HttpServletRequest request) throws IOException{
		System.err.println("3");
		Long startTime = System.currentTimeMillis();
		CommonsMultipartResolver multipartResolver = new CommonsMultipartResolver(request.getSession().getServletContext());
		//检查form中是否有enctype="multipart/form-data"
		if (multipartResolver.isMultipart(request)) {
			MultipartHttpServletRequest multipartHttpServletRequest = (MultipartHttpServletRequest) request;
			 //获取multiRequest 中所有的文件名
			Iterator iterator = multipartHttpServletRequest.getFileNames();
			while(iterator.hasNext()){
				MultipartFile file = multipartHttpServletRequest.getFile(iterator.next().toString());
				if (file!=null) {
					String path = "F:/testupload/"+System.currentTimeMillis()+file.getOriginalFilename();
					//上传文件
					file.transferTo(new File(path));
				}
			}
		}
		long  endTime=System.currentTimeMillis();
		System.out.println("上传文件需要的时间为:"+(endTime-startTime));
		return "redirect:/banner/show.do"; 
	}
	
	 @RequestMapping("/hello")
	 @ResponseBody
	 public String index(String id) {
		 System.out.println("id:"+id);
	        return "Hello World";
	    }

}
